using System;
using System.Text;
using System.ComponentModel;
using CodeSmith.Engine;
using CodeSmith.CustomProperties;
using System.Data;
using System.Security.Principal;
using SchemaExplorer;

namespace Pantheon.BaseTemplates
{
	public class GenericTemplate : CodeSmith.BaseTemplates.OutputFileCodeTemplate
	{
		// file names
		public string GetDALBaseName(string subNamespace)
		{
			return subNamespace + "Base";
		}
		public string GetDALManagerName(string subNamespace)
		{
			return subNamespace + "Manager" ;
		}

		public string GetDALObjectName(TableSchema table)
		{
			return GetDALObjectName(table.Name);
		}
		
		public string GetDALObjectName(string root)
		{
			return "D" + root;
		}

		public string GetInfoItemName(TableSchema table)
		{
			return GetClassName(table) + "Info" ;
		}
		
		public string GetInfoItemName(string className)
		{
			return className + "Info";
		}
		
		public string GetInfoCollectionName(TableSchema table)
		{
			return GetInfoCollectionName(GetClassName(table));
		}

		public string GetInfoCollectionName(string root)
		{
			return root + "InfoCollection";
		}

		public bool IsPantheon(string nameSpace)
		{
			return nameSpace.IndexOf("Pantheon") > -1;
		}

		public string CLSCompliant(string nameSpace)
		{
			return "[CLSCompliant(true)]";
		}

		public string CommonClass(string nameSpace)
		{
			return nameSpace+".Global";
		}

		public string GetMethodTablePart(TableSchema table)
		{
			return GetMethodTablePart(table.Name);							
		}

		public string GetMethodTablePart(string root)
		{
			string s = root;
			//if (s.ToLower().EndsWith("s"))
			//	s = s.Substring(0, s.Length - 1);
			return s;							
		}
		
		public string GetClassName(TableSchema table)
		{
			return GetClassName(table.Name);
		}

		public string GetClassName(string root)
		{
			string s = root;
			if (s.ToLower().EndsWith("s"))
			if (!s.ToLower().EndsWith("ss"))
				s = s.Substring(0, s.Length - 1);

			if (s.ToLower().EndsWith("info"))
				s = s.Substring(0, s.Length - 4);

			return GetPascalCaseName(s);
		}

		public string PantheonInfoSpace
		{
			get
			{
				return "PantheonSoftware.InfoCollection";
			}
		}
		
		public string DBNamespace(string nameSpace)
		{
			if (IsPantheon(nameSpace))
				return "Pantheon.DataProvider";
			return "System.Data.SqlClient";
		}
		
		public string TraceProvider(string nameSpace)
		{
			return "System.Diagnostics";
		}

		
		public string GetFullParameterCreation(ColumnSchema column)
		{
			string strReturnString = "";
			
			strReturnString += "new SqlParameter(\"@";
			strReturnString += column.Name + "\" ,";
			strReturnString += "SqlDbType." + GetSqlDbType(column) + ", ";
			if (GetSqlDbType(column) == "UniqueIdentifier")
				strReturnString += "16, ";
			else
				strReturnString += column.Size + ", ";
			
			strReturnString += "ParameterDirection.Input, false, 0, 0, \"\", DataRowVersion.Current, value)";	
			
			return strReturnString;
		}

		public ColumnSchema GetColumn(TableSchema Table, string ColumnName)
		{
			return Table.Columns[Table.Columns.IndexOf(ColumnName)];
		}

		public string GetParameterCreation(ColumnSchema column, string nameSpace)
		{
			return GetParameterCreation(column);
		}
		
		public string GetParameterCreation(ColumnSchema column)
		{
			string nativeType = column.NativeType.ToString();
			string strReturnString = "\"@";
			strReturnString += column.Name + "\", ";
			strReturnString += "SqlDbType." + GetSqlDbType(column) + ", ";
			if (GetDbType(column) == "UniqueIdentifier")
				strReturnString += "16, ";
			else
				strReturnString += column.Size + ", ";
			
			strReturnString += "\"" + column.Name + "\"";
			
			return strReturnString;
				
		}
		
		public string GetParameterName(ColumnSchema column)
		{
			return "\"@" + column.Name + "\"";
		}
		
		public string GetSummary(string src)
		{
			if (src.ToUpper().Equals("HANDLER"))
				return "Intials of the user who performed the last update";
			if (src.ToUpper().Equals("TRANSACT_DATE"))
				return "Date and time of the last update";
			return "TODO: describe property " + GetCaseName(src);
		}

		public string GetPropertyName(string src)
		{
			if (src.ToUpper().Equals("HANDLER"))
				return "LastUpdatedBy";
			if (src.ToUpper().Equals("TRANSACT_DATE"))
				return "LastUpdate";
			return GetCaseName(src);
		}
		
		public string GetCaseName(string src)
		{
			string newStr = "";
			string[] tmp;
			
			// a new table with upper and lower cases? then just remove _
			if (string.Compare(src, src.ToUpper(), false) != 0)
				return src.Replace("_", "");
			
			// old tables:
			if (src.IndexOf("_") > -1 || src.IndexOf(src.ToUpper()) > -1)
				tmp = src.ToLower().Split('_');
			else
				tmp = src.Split('_');
			foreach (string s in tmp)
			{
				newStr+= s[0].ToString().ToUpper() + s.Substring(1, s.Length - 1);
			}
			return newStr.Replace("Ident", "Id");
		}
		
		public string GetCSReturnParameter(string nameSpace)
		{
			return "\"@RETURN_VALUE\", DbType.Int32, 4, ParameterDirection.ReturnValue, false, ((System.Byte)(0)), ((System.Byte)(0)), \"\", DataRowVersion.Current, null";
		}
		public string GetReturnParameter(string nameSpace)
		{
			return "\"@RETURN_VALUE\", DbType.Int32, 4, ParameterDirection.ReturnValue, false, (0), (0), \"\", DataRowVersion.Current, Nothing";
		}

		public string GetCamelCaseName(string value)
		{
			return value.Substring(0, 1).ToLower() + value.Substring(1);
		}
		
		public string GetPascalCaseName(string src)
		{
			string newStr = "";
			string[] tmp;
			if (src.IndexOf("_") > -1 || src.IndexOf(src.ToUpper()) > -1)
				tmp = src.ToLower().Split('_');
			else
				tmp = src.Split('_');
			foreach (string s in tmp)
			{
				if (s.Length > 0)
					newStr+= s[0].ToString().ToUpper() + s.Substring(1, s.Length - 1);
			}
			return newStr;
		}
		
		public string GetSpacedName(string value)
		{
			StringBuilder spacedName = new StringBuilder();
			
			for (int i = 0; i < value.Length; i++)
			{
				if (i > 0 && i < value.Length - 1 && value.Substring(i, 1).ToUpper() == value.Substring(i, 1))
				{
					spacedName.Append(" ");
				}
				spacedName.Append(value[i]);
			}
			
			return spacedName.ToString();
		}
		
		public string GetFillByIndexName(IndexSchema index)
		{
			StringBuilder fillByIndexName = new StringBuilder();
			
			fillByIndexName.Append("FillBy");
			
			for (int i = 0; i < index.MemberColumns.Count; i++)
			{
				fillByIndexName.Append(index.MemberColumns[i].Name.Replace(" ", ""));
				if (i < index.MemberColumns.Count - 1)
				{
					fillByIndexName.Append("And");
				}
			}
			
			return fillByIndexName.ToString();
		}
		
		public string GetFillByIndexParameters(IndexSchema index)
		{
			StringBuilder fillByIndexParameters = new StringBuilder();
			
			for (int i = 0; i < index.MemberColumns.Count; i++)
			{
				fillByIndexParameters.Append(GetCSharpVariableType(index.MemberColumns[i]));
				fillByIndexParameters.Append(" ");
				fillByIndexParameters.Append(GetCamelCaseName(index.MemberColumns[i].Name));
				
				if (i < index.MemberColumns.Count - 1)
				{
					fillByIndexParameters.Append(", ");
				}
			}
			
			return fillByIndexParameters.ToString();
		}
		
		public string GetMemberVariableName(string value)
		{
			string memberVariableName = "_" + GetCamelCaseName(value);
			
			return memberVariableName;
		}
		
		public string GetPropertyComparison(ColumnSchema column)
		{
			return GetPropertyComparison(column.Name, column.DataType, column.SystemType);
		}

		public string GetPropertyComparison(CommandResultColumnSchema column)
		{
			return GetPropertyComparison(column.Name, column.DataType, column.SystemType);
		}
		
		public string GetPropertyComparison(string columnName, DbType dataType, Type systemType)
		{
			string returnstring = "";
			switch (dataType)
			{
				case DbType.Decimal:
				case DbType.Double:
				case DbType.Int16:
				case DbType.Int32:
				case DbType.Int64:
				case DbType.Single:
				case DbType.UInt16:
				case DbType.UInt32:
				case DbType.UInt64:
				case DbType.DateTime:
				case DbType.Currency:
					returnstring = string.Format("{0}.Parse(this.Row[\"{1}\"].ToString()) != value", SimplifyCSType(systemType.ToString()), columnName);
					break;
				default:
					returnstring = string.Format("this.Row[\"{0}\"].ToString() != value", columnName);
					break;
			}
			return returnstring;			
		}
		
		public string GetSqlParameterExtraParams(string statementPrefix, ColumnSchema column)
		{
			if (SizeMatters(column) && PrecisionMatters(column))
			{
				return ");\r\n" + statementPrefix + "prm.Scale = " + column.Scale + ";\r\n" + statementPrefix + "prm.Precision = " + column.Precision + ";";
			}
			else if (SizeMatters(column))
			{
				return ", " + column.Size + ");";
			}
			else
			{
				return ");";
			}
		}
		
		public bool SizeMatters(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.String:
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.Decimal:
				{
					return true;
				}
				default:
				{
					return false;
				}
			}
		}
		
		public bool PrecisionMatters(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.Decimal:
				{
					return true;
				}
				default:
				{
					return false;
				}
			}
		}
		
		public string GetMemberVariableDeclarationStatement(ColumnSchema column)
		{
			return GetMemberVariableDeclarationStatement("protected", column);
		}
		
		public string GetMemberVariableDeclarationStatement(string protectionLevel, ColumnSchema column)
		{
			string statement = protectionLevel + " ";
			statement += GetCSharpVariableType(column) + " " + GetMemberVariableName(column.Name);
			
			string defaultValue = GetMemberVariableDefaultValue(column);
			if (defaultValue != "")
			{
				statement += " = " + defaultValue;
			}
			
			statement += ";";	
			
			return statement;
		}
		
		public string GetSqlReaderAssignmentStatement(ColumnSchema column, int index)
		{
			string statement = "if (!reader.IsDBNull(" + index.ToString() + ")) ";
			statement += GetMemberVariableName(column.Name) + " = ";
			
			if (column.Name.EndsWith("TypeCode")) 
				statement += "(" + column.Name + ")";
			
			statement += "reader." + GetReaderMethod(column) + "(" + index.ToString() + ");";
			
			return statement;
		}
		
		public string GetValidateStatements(TableSchema table, string statementPrefix)
		{
			string statements = "";
			
			foreach (ColumnSchema column in table.Columns)
			{
				if (IncludeEmptyCheck(column))
				{
					statements += "\r\n" + statementPrefix + "if (" + GetMemberVariableName(column.Name) + " == " + GetMemberVariableDefaultValue(column) + ") this.ValidationErrors.Add(new ValidationError(ValidationTypeCode.Required, \"" + table.Name + "\", \"" + column.Name + "\", \"" + column.Name + " is required.\"));";
				}
				if (IncludeMaxLengthCheck(column))
				{
					statements += "\r\n" + statementPrefix + "if (" + GetMemberVariableName(column.Name) + ".Length > " + column.Size.ToString() + ") this.ValidationErrors.Add(new ValidationError(ValidationTypeCode.MaxLength, \"" + table.Name + "\", \"" + column.Name + "\", \"" + column.Name + " is too long.\"));";
				}
			}
			
			return statements.Substring(statementPrefix.Length + 2);
		}
		
		public string GetPropertyName(ColumnSchema column)
		{
			string propertyName = column.Name;
			
			if (propertyName == column.Table.Name + "Name") return "Name";
			if (propertyName == column.Table.Name + "Description") return "Description";
			
			if (propertyName.EndsWith("TypeCode")) propertyName = propertyName.Substring(0, propertyName.Length - 4);
			
			return propertyName;
		}

		public string GetVBPropertyReturnValue(ColumnSchema column)
		{
			if (column.Name.EndsWith("TypeCode")) return column.Name;
			
			switch (column.DataType)
			{
				case DbType.AnsiString: 
				case DbType.AnsiStringFixedLength: 
				case DbType.StringFixedLength: 
				case DbType.String: return "Convert.ToString(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Binary: 
					if (column.NativeType == "timestamp")
						return "Convert.ToDateTime(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
					else
						return "()byte";
				case DbType.Boolean: return "Convert.ToBoolean(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Byte: return "byte";
				case DbType.Currency: return "Convert.ToDouble(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Date: return "Convert.ToDateTime(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.DateTime: return "Convert.ToDateTime(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Decimal: 
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "Convert.ToInt64(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
						else
							return "Convert.ToInt32(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
					else
						return "Convert.ToDouble(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Double: return "Convert.ToDouble(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Guid: return "Guid";
				case DbType.Int16: return "Convert.ToInt16(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Int32: return "Convert.ToInt32(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Int64: return "Convert.ToInt64(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				case DbType.Object: return "object";
				case DbType.SByte: return "sbyte";
				case DbType.Single: return "single";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "uint16";
				case DbType.UInt32: return "uint32";
				case DbType.UInt64: return "uint64";
				case DbType.VarNumeric: return "Convert.ToDouble(this.Row(\"" + column.Name + "\"), CultureInfo.InvariantCulture)";
				default:
				{
					return "__UNKNOWN__" + column.NativeType;
				}
			}
		}
		public string GetCSPropertyReturnValue(ColumnSchema column)
		{
			return GetCSPropertyReturnValue(column.Name, column.SystemType); 
		}
		
		public string GetCSPropertyReturnValue(CommandResultColumnSchema column)
		{
			return GetCSPropertyReturnValue(column.Name, column.SystemType); 
		}

		public string GetCSPropertyReturnValue(string columnName, System.Type columnType)
		{
			if (columnName.EndsWith("TypeCode")) return columnName;
			
			switch (columnType.ToString())
			{
				case "System.String": return "Convert.ToString(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.DateTime": return "Convert.ToDateTime(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Boolean": return "Convert.ToBoolean(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Byte": return "byte";
				case "System.Currency": return "Convert.ToDouble(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Int16": return "Convert.ToInt16(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Int32": return "Convert.ToInt32(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Int64": return "Convert.ToInt64(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Double" : return "Convert.ToDouble(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
				case "System.Decimal" : return "Convert.ToDecimal(this.Row[\"" + columnName + "\"], CultureInfo.InvariantCulture)";
/*				case DbType.Object: return "object";
				case DbType.SByte: return "sbyte";
				case DbType.Single: return "single";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "uint16";
				case DbType.UInt32: return "uint32";
				case DbType.UInt64: return "uint64";
				case DbType.VarNumeric: return "Convert.ToDouble(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
*/				default:
				{
					return "__UNKNOWN__" + columnType.ToString();
				}
			}
		}
/*		
		public string GetCSPropertyReturnValue(string columnName, DbType columnType, int columnScale, Byte columnPrecision)
		{
			if (column.Name.EndsWith("TypeCode")) return column.Name;
			
			switch (column.DataType)
			{
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.StringFixedLength:
				case DbType.String: return "Convert.ToString(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Binary: 
					if (column.NativeType == "timestamp")
						return "Convert.ToDateTime(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
					else
						return "()byte";
				case DbType.Boolean: return "Convert.ToBoolean(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Byte: return "byte";
				case DbType.Currency: return "Convert.ToDouble(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Date: return "Convert.ToDateTime(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.DateTime: return "Convert.ToDateTime(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Decimal: 
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "Convert.ToInt64(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
						else
							return "Convert.ToInt32(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
					else
						return "Convert.ToDouble(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Double: return "Convert.ToDouble(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Guid: return "Guid";
				case DbType.Int16: return "Convert.ToInt16(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Int32: return "Convert.ToInt32(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Int64: return "Convert.ToInt64(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				case DbType.Object: return "object";
				case DbType.SByte: return "sbyte";
				case DbType.Single: return "single";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "uint16";
				case DbType.UInt32: return "uint32";
				case DbType.UInt64: return "uint64";
				case DbType.VarNumeric: return "Convert.ToDouble(this.Row[\"" + column.Name + "\"], CultureInfo.InvariantCulture)";
				default:
				{
					return "__UNKNOWN__" + column.NativeType;
				}
			}
		}
*/
		public string GetVBVariableType(ColumnSchema column)
		{
			if (column.Name.EndsWith("TypeCode")) return column.Name;
			
			switch (column.DataType)
			{
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.StringFixedLength:
				case DbType.String: return "String";
				case DbType.Binary:
					if (column.NativeType == "timestamp")
						return "DateTime";
					else
						return "byte[]";
				case DbType.Boolean: return "Boolean";
				case DbType.Byte: return "Byte";
				case DbType.Currency: return "Double";
				case DbType.Date:
				case DbType.DateTime: return "DateTime";
				case DbType.Decimal:
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "Long";
						else
							return "Int";
					else
						return "Double";
				case DbType.Double:
				case DbType.VarNumeric: return "Double";
				case DbType.Guid: return "Guid";
				case DbType.Int16: return "Short";
				case DbType.Int32: return "Integer";
				case DbType.Int64: return "Long";
				case DbType.Object: return "Object";
				case DbType.SByte: return "Sbyte";
				case DbType.Single: return "Single";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "Uint16";
				case DbType.UInt32: return "Uint32";
				case DbType.UInt64: return "Uint64";
				default:
				{
					return "__UNKNOWN__" + column.NativeType;
				}
			}
		}

		// returns the variable data type.
		public string GetCSharpVariableType(ColumnSchema column)
		{
			if (column.Name.EndsWith("TypeCode")) return column.Name;
			
			switch (column.DataType)
			{
				case DbType.AnsiString: return "string";
				case DbType.AnsiStringFixedLength: return "string";
				case DbType.Binary: 
					if (column.NativeType == "timestamp")
						return "DateTime";
					else
						return "byte[]";
				case DbType.Boolean: return "bool";
				case DbType.Byte: return "byte";
				case DbType.Currency: return "Decimal";
				case DbType.Date: return "DateTime";
				case DbType.DateTime: return "DateTime";
				case DbType.Decimal:
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "long";
						else
							return "int";
					else
						return "double";
				case DbType.Double: return "double";
				case DbType.Guid: return "Guid";
				case DbType.Int16: return "short";
				case DbType.Int32: return "int";
				case DbType.Int64: return "long";
				case DbType.Object: return "object";
				case DbType.SByte: return "sbyte";
				case DbType.Single: return "float";
				case DbType.String: return "string";
				case DbType.StringFixedLength: return "string";
				case DbType.Time: return "TimeSpan";
				case DbType.UInt16: return "ushort";
				case DbType.UInt32: return "uint";
				case DbType.UInt64: return "ulong";
				case DbType.VarNumeric: return "Decimal";
				default:
				{
					return "__UNKNOWN__" + column.NativeType;
				}
			}
		}

		
		public string SetterReturnIfNull(System.Data.DbType dataType)
		{
			switch (dataType)
			{
				case DbType.AnsiString: return "\"\"";
				case DbType.AnsiStringFixedLength: return "\"\"";
				case DbType.Boolean: return "false";
				case DbType.Binary:
				case DbType.Byte: 
					if (dataType.ToString() == "timestamp")
						return "Pantheon.General.Utility.GetInitializedDateTime()";
					else
						return "0";
				case DbType.Currency: return "0";
				case DbType.Date: return "DateTime.MinValue";
				case DbType.DateTime: return "DateTime.MinValue";
				case DbType.Decimal: return "0";
				case DbType.Double: return "0";
				case DbType.Guid: return "Guid.Empty";
				case DbType.Int16: return "0";
				case DbType.Int32: return "0";
				case DbType.Int64: return "0";
				case DbType.Object: return "null";
				case DbType.SByte: return "0";
				case DbType.Single: return "0";
				case DbType.String: return "\"\"";
				case DbType.StringFixedLength: return "\"\"";
				case DbType.Time: return "TimeSpan.MinValue";
				case DbType.UInt16: return "0";
				case DbType.UInt32: return "0";
				case DbType.UInt64: return "0";
				case DbType.VarNumeric: return "0";
				default:
				{
					return "__UNKNOWN__" + dataType;
				}
			}
		}

		public string SetterReturnIfNull(ColumnSchema column)
		{
			return SetterReturnIfNull(column.DataType);
		}
		
		public string SetterReturnIfNull(CommandResultColumnSchema column)
		{
			return SetterReturnIfNull(column.DataType);
		}

		public string GetReaderMethod(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.Byte:
				{
					return "GetByte";
				}
				case DbType.Int16:
				{
					return "GetInt16";
				}
				case DbType.Int32:
				{
					return "GetInt32";
				}
				case DbType.Int64:
				{
					return "GetInt64";
				}
				case DbType.AnsiStringFixedLength:
				case DbType.AnsiString:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					return "GetString";
				}
				case DbType.Boolean:
				{
					return "GetBoolean";
				}
				case DbType.Guid:
				{
					return "GetGuid";
				}
				case DbType.Currency:
				case DbType.Decimal:
				{
					return "GetDecimal";
				}
				case DbType.DateTime:
				case DbType.Date:
				{
					return "GetDateTime";
				}
				default:
				{
					return "__SQL__" + column.DataType;
				}
			}
		}

		public string GetSqlDbType(ColumnSchema column)
		{
			switch (column.NativeType)
			{
				case "bigint": return "BigInt";
				case "binary": return "Binary";
				case "bit": return "Bit";
				case "char": return "Char";
				case "datetime": return "DateTime";
				case "decimal": return "Decimal";
				case "float": return "Float";
				case "image": return "Image";
				case "int": return "Int";
				case "money": return "Money";
				case "nchar": return "NChar";
				case "ntext": return "NText";
				case "numeric": return "Decimal";
				case "nvarchar": return "NVarChar";
				case "real": return "Real";
				case "smalldatetime": return "SmallDateTime";
				case "smallint": return "SmallInt";
				case "smallmoney": return "SmallMoney";
				case "sql_variant": return "Variant";
				case "sysname": return "NChar";
				case "text": return "Text";
				case "timestamp": return "Timestamp";
				case "tinyint": return "TinyInt";
				case "uniqueidentifier": return "UniqueIdentifier";
				case "varbinary": return "VarBinary";
				case "varchar": return "VarChar";
				case "FUNCNAME": return "VarChar";
				case "INIT": return "VarChar";
				case "TABLE_IDENT": return "Decimal";
				case "TABLE_IDENT_REF": return "Decimal";
				default: return "__UNKNOWN__" + column.NativeType;
			}
		}
		
		// gets the data type for the DbType enum.
		public string GetDbType(ColumnSchema column)
		{
			switch (column.NativeType)
			{
				case "bigint": return "Int64";
				case "binary": return "Binary";
				case "bit": return "Boolean";
				case "char": return "AnsiStringFixedLength";
				case "timestamp":
				case "datetime": return "DateTime";
				case "decimal": return "Decimal";
				case "float": return "Decimal";
				case "image": return "Image";
				case "int": return "Int32";
				case "money": return "Currency";
				case "nchar": return "StringFixedLength";
				case "ntext": return "String";
				case "numeric": 
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "Int64";
						else
							return "Int32";
					else
						return "Decimal";
				case "nvarchar": return "String";
				case "real": return "Single";
				case "smalldatetime": return "SmallDateTime";
				case "smallint": return "Int16";
				case "smallmoney": return "Currency";
				case "sql_variant": return "Object";
				case "sysname": return "NChar";
				case "text": return "Text";
				case "tinyint": return "Byte";
				case "uniqueidentifier": return "Guid";
				case "varbinary": return "Binary";
				case "varchar": return "String";
				case "FUNCNAME": return "String";
				case "INIT": return "String";
				case "TABLE_IDENT": 
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "Int64";
						else
							return "Int32";
					else
						return "Decimal";
				case "TABLE_IDENT_REF": 
					if (column.Scale == 0)
						if (column.Precision > 9)
							return "Int64";
						else
							return "Int32";
					else
						return "Decimal";
				default: return "__UNKNOWN__" + column.NativeType;
			}
		}
		
		public string SimplifyCSType(string type)
		{
			int pos = type.IndexOf(".");
			if (type.StartsWith("System"))
				type = type.Substring(pos+1, type.Length - pos - 1);
			switch(type)
			{
				case "Int16": return "short";
				case "Int32": return "int";
				case "Int64": return "long";
				case "String": return "string";
				default: return type;
			}
		}
		
		public string GetMemberVariableDefaultValue(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.Guid:
				{
					return "Guid.Empty";
				}
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					return "String.Empty";
				}
				default:
				{
					return "";
				}
			}
		}
		
		public bool IncludeMaxLengthCheck(ColumnSchema column)
		{
			switch (column.DataType)
			{
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					return true;
				}
				default:
				{
					return false;
				}
			}
		}
		
		public bool IncludeEmptyCheck(ColumnSchema column)
		{
			if (column.IsPrimaryKeyMember || column.AllowDBNull || column.Name.EndsWith("TypeCode")) return false;
	
			switch (column.DataType)
			{
				case DbType.Guid:
				{
					return true;
				}
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					return true;
				}
				default:
				{
					return false;
				}
			}
		}
		
		public string GetSqlParameterStatement(ColumnSchema column)
		{
			return GetSqlParameterStatement(column, false);
		}
		
		public string GetSqlParameterStatement(ColumnSchema column, bool isOutput)
		{
			string param = "@" + column.Name + " " + column.NativeType;
			if (IsUserDefinedType(column))
				return param;
				
			switch (column.DataType)
			{
				case DbType.Decimal:
				{
					param += "(" + column.Precision + ", " + column.Scale + ")";
					break;
				}
				case DbType.AnsiString:
				case DbType.AnsiStringFixedLength:
				case DbType.String:
				case DbType.StringFixedLength:
				{
					if (column.Size > 0)
						param += "(" + column.Size + ")";
					break;
				}
			}
			
			if (isOutput)
				param += " OUTPUT";
			
			return param;
		}
		
		public bool IsUserDefinedType(ColumnSchema column)
		{
			if ((column.NativeType == "TABLE_IDENT")
				|| (column.NativeType == "INIT")
				|| (column.NativeType == "TABLE_IDENT_REF")
				|| (column.NativeType == "UserName")
			)
				return true;
			return false;
		}
		
		public string CurrentUser()
		{
			WindowsIdentity ident = WindowsIdentity.GetCurrent();
        	String s = ident.Name;
        	if (ident.Name.LastIndexOf(@"\") > 0)
            	s = s.Substring(ident.Name.LastIndexOf(@"\") + 1);
        	return s;
		}
		
		#region CommandSchema Helpers
		
		public CommandResultSchemaCollection GetSpInfo(CommandSchema command)
		{
			CommandResultSchemaCollection crs = command.CommandResults;
			return crs;
			
		}
		
		#endregion
		
		[FileDialog(FileDialogType.Save, Title="Select Output File", Filter="C# Files (*.cs)|*.cs", DefaultExtension=".cs")]
		public override string OutputFile
		{
			get {return base.OutputFile;}
			set {base.OutputFile = value;}
		}
		
	}
}
